#include<iostream>
#include<unistd.h>
#include<vector>
#include<sys/wait.h>
#include<sys/types.h>
#include<string>
#include<functional>
#include "Task.hpp"
#include"Channel.hpp"
using namespace std;

using work_t = function<void()>;
enum{
    OK=0,
    UsageError,
    PipeError,
    ForkError
};

class ProcessPool
{
public:
    ProcessPool(int n, work_t w):processnum(n), work(w)
    {
    }
    int InitProcess()
    {
        for(int i = 0; i < processnum; i++)
        {
            //1.先有管道
            int pipefd[2] = {0};
            int n = pipe(pipefd);
            if(n < 0)   return 2;
            //创建进程
            pid_t id = fork();
            if(id < 0)  return 3;//创建失败
            if(id == 0)
            {
                ::close(pipefd[1]);//only read
                //child
                dup2(pipefd[0],0);
                Worker();
                exit(0);
            }
            //father
            ::close(pipefd[0]);//only write
            channels.emplace_back(pipefd[1],id);

        }
        return OK;
    }
    //测试函数
    void DebugPrint()
    {
        for(auto& e : channels)
        {
            cout<<e.Name()<<endl;
        }
    }
    void DisPatchTask()
    {
        int who = 0;
        int num  = 20;
            //派发任务
            while(num--)
            {
                //a.选择任务
                int task = tm.SelectTask();
                //b.选择一个子进程
                Channel& curr = channels[who++];
                who %= channels.size();

                cout<<"###########################"<<endl;
                cout<<"send "<<task<<" to"<<curr.Name()<<", 任务还剩:"<<num<<endl;
                cout<<"###########################"<<endl;
                //c.派发任务
                curr.Send(task);
                sleep(1);
            }
    }

    void ClearProcessPool()
    {
        for(auto e : channels)
        {
            e.Close();
        }
        for(auto& e :channels)
        {
            pid_t rid = waitpid(e.id(), nullptr, 0);
            if(rid > 0)
            {
                cout<<"child "<<rid<<" wait ... success"<<endl;
            }
        }
    }
private:
    vector<Channel> channels;
    int processnum;
    work_t work;
};

